package com.guochenglang.www.util.lru;

import com.guochenglang.www.util.connect.Config;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 基于LRU模式缓存淘汰的容器
 *
 * @author 郭程朗
 */
public class MyCapacity {
    /**
     * 容器大小
     */
    private static int capacity;
    /**
     * 缓存容器
     */
    private static final Map<Object, Object> LRU_MAP = Collections.synchronizedMap(new LinkedHashMap<>());
    private static final MyCapacity MY_CAPACITY = new MyCapacity();

    private MyCapacity() {
    }


    //静态代码块对MyCapacity的容量进行初始化
    static {
        Properties prop = new Properties();
        InputStream inputStream = Config.class.getClassLoader().getResourceAsStream("LRU.properties");
        try {
            prop.load(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        capacity = Integer.parseInt(prop.getProperty("capacity"));

    }


    /**
     * 根据键获取缓存内容
     *
     * @param key 键
     * @return 值
     */
    public static Object get(Object key) {
        //不存在该键
        if (!LRU_MAP.containsKey(key)) {
            return null;
        }
        //存在该键，将该键添加到最近使用
        System.out.println("缓存获取");
        MY_CAPACITY.recentUse(key);
        //返回值
        return LRU_MAP.get(key);
    }

    public static void put(Object key, Object value) {
        //包含了，修改值
        if (LRU_MAP.containsKey(key)) {
            LRU_MAP.put(key, value);
            //放队尾
            MY_CAPACITY.recentUse(key);
            return;
        }
        //缓存已满，删除最近未少使用的数据
        if (LRU_MAP.size() >= capacity) {
            Set<Object> keySet = LRU_MAP.keySet();
            //删除表头元素
            for (Object s : keySet) {
                LRU_MAP.remove(s);
                break;
            }
            //存到队尾
            LRU_MAP.put(key, value);
            return;
        }
        //正常情况
        LRU_MAP.put(key, value);
    }

    private void recentUse(Object key) {
        Object value = LRU_MAP.get(key);
        //删除对应key
        LRU_MAP.remove(key);
        //放置到队尾
        LRU_MAP.put(key, value);
    }

    public static String getKey(Integer id, String pojo) {
        return pojo + id.toString();
    }
}
